home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / src / exampleCode / opengl / toogl / perlclass.h < prev    next >
C/C++ Source or Header  |  1996-11-11  |  17KB  |  693 lines

  1. /*
  2.  * Copyright (c) 1992, 1993 Silicon Graphics, Inc.
  3.  *
  4.  * Permission to use, copy, modify, distribute, and sell this software and
  5.  * its documentation for any purpose is hereby granted without fee, provided
  6.  * that (i) the above copyright notices and this permission notice appear in
  7.  * all copies of the software and related documentation, and (ii) the name of
  8.  * Silicon Graphics may not be used in any advertising or publicity relating 
  9.  * to the software without the specific, prior written permission of 
  10.  * Silicon Graphics.
  11.  *
  12.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF
  13.  * ANY KIND, EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, 
  14.  * ANY WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
  15.  *
  16.  * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR ANY SPECIAL, INCIDENTAL, 
  17.  * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER 
  18.  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF 
  19.  * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT 
  20.  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  21.  */
  22.  
  23. /*
  24.  * Version 1.6
  25.  * Written by Jim Morris,  jegm@sgi.com
  26.  * Kudos to Larry Wall for inventing Perl
  27.  * Copyrights only exist on the regex stuff, and all have been left intact.
  28.  * The only thing I ask is that you let me know of any nifty fixes or
  29.  * additions.
  30.  * 
  31.  * Credits:
  32.  * I'd like to thank Michael Golan <mg@Princeton.EDU> for his critiques
  33.  * and clever suggestions. Some of which have actually been implemented
  34.  */
  35.  
  36. #ifndef    _PERL_H
  37. #define    _PERL_H
  38.  
  39. #include <string.h>
  40. #include "regexp.h"
  41.  
  42. #if    DEBUG
  43. #include    <stdio.h>
  44. #endif
  45.  
  46. #define    INLINE    inline
  47.  
  48. // This is the base class for PerlList, it handles the underlying
  49. // dynamic array mechanism
  50.  
  51. template<class T>
  52. class PerlListBase
  53. {
  54. private:
  55.     enum{ALLOCINC=20};
  56.     T *a;
  57.     int cnt;
  58.     int first;
  59.     int allocated;
  60.     int allocinc;
  61.     void grow(int amnt= 0, int newcnt= -1);
  62.  
  63. protected:
  64.     void compact(const int i);
  65.  
  66. public:
  67. #ifdef    USLCOMPILER
  68.     // USL 3.0 bug with enums losing the value
  69.     PerlListBase(int n= 20)
  70. #else
  71.     PerlListBase(int n= ALLOCINC)
  72. #endif
  73.     {
  74.     a= new T[n];
  75.     cnt= 0;
  76.         first= n>>1;
  77.     allocated= n;
  78.     allocinc= n;
  79. #    ifdef    DEBUG
  80.     fprintf(stderr, "PerlListBase(int %d) a= %p\n", allocinc, a);
  81. #    endif
  82.     }
  83.  
  84.     PerlListBase(const PerlListBase<T>& n);
  85.     PerlListBase<T>& PerlListBase<T>::operator=(const PerlListBase<T>& n);
  86.     virtual ~PerlListBase(){
  87. #       ifdef    DEBUG
  88.     fprintf(stderr, "~PerlListBase() a= %p, allocinc= %d\n", a, allocinc);
  89. #       endif
  90.     delete [] a;
  91.     }
  92.  
  93.     INLINE T& operator[](const int i);
  94.     INLINE const T& operator[](const int i) const;
  95.  
  96.     int count(void) const{ return cnt; }
  97.  
  98.     void add(const T& n);
  99.     void add(const int i, const T& n);
  100.     void erase(void){ cnt= 0; first= (allocated>>1);}
  101. };
  102.  
  103. // PerlList
  104. class PerlStringList;
  105.  
  106. template <class T>
  107. class PerlList: private PerlListBase<T>
  108. {
  109. public:
  110.  
  111.     PerlList(int sz= 10): PerlListBase<T>(sz){}
  112.  
  113.     // stuff I want public to see from PerlListBase
  114.     T& operator[](const int i){return PerlListBase<T>::operator[](i);}
  115.     const T& operator[](const int i) const{return PerlListBase<T>::operator[](i);}
  116.     PerlListBase<T>::count;
  117.  
  118.     // add perl-like synonym
  119.     void reset(void){ erase(); }
  120.     int scalar(void) const { return count(); }
  121.  
  122.     operator void*() { return count()?this:0; } // so it can be used in tests
  123.     int isempty(void) const{ return !count(); } // for those that don't like the above (hi michael)
  124.  
  125.     T pop(void)
  126.     {
  127.     T tmp;
  128.     int n= count()-1;
  129.     if(n >= 0){
  130.         tmp= (*this)[n];
  131.         compact(n);
  132.     }
  133.     return tmp;
  134.     }
  135.  
  136.     void push(const T& a){ add(a);}
  137.     void push(const PerlList<T>& l);
  138.  
  139.     T shift(void)
  140.     {
  141.     T tmp= (*this)[0];
  142.     compact(0);
  143.     return tmp;
  144.     }
  145.     
  146.     int unshift(const T& a)
  147.     {
  148.     add(0, a);
  149.     return count();
  150.     }
  151.     
  152.     int unshift(const PerlList<T>& l);
  153.  
  154.     PerlList<T> reverse(void);
  155.     PerlList<T> sort();
  156.     
  157.     PerlList<T> splice(int offset, int len, const PerlList<T>& l);
  158.     PerlList<T> splice(int offset, int len);
  159.     PerlList<T> splice(int offset);
  160. };
  161.  
  162. // just a mechanism for self deleteing strings which can be hacked
  163. class TempString
  164. {
  165. private:
  166.     char *str;
  167. public:
  168.     TempString(const char *s)    
  169.     {
  170.         str= new char[strlen(s) + 1];
  171.         strcpy(str, s);
  172.     }
  173.     
  174.     TempString(const char *s, int len)    
  175.     {
  176.         str= new char[len + 1];
  177.         if(len) strncpy(str, s, len);
  178.         str[len]= '\0';
  179.     }
  180.  
  181.     ~TempString(){ delete [] str; }
  182.  
  183.     operator char*() const { return str; }
  184. };
  185.  
  186. /*
  187.  * This class takes care of the mechanism behind variable length strings
  188.  */
  189.  
  190. class VarString
  191. {
  192. private:
  193.     enum{ALLOCINC=32};
  194.     char *a;
  195.     int len;
  196.     int allocated;
  197.     int allocinc;
  198.     INLINE void grow(int n= 0);
  199.  
  200. public:
  201. #ifdef    USLCOMPILER
  202.     // USL 3.0 bug with enums losing the value
  203.     INLINE VarString(int n= 32);
  204. #else
  205.     INLINE VarString(int n= ALLOCINC);
  206. #endif
  207.  
  208.     INLINE VarString(const VarString& n);
  209.     INLINE VarString(const char *);
  210.     INLINE VarString(const char* s, int n);
  211.     INLINE VarString(char);
  212.  
  213.     ~VarString(){
  214. #       ifdef    DEBUG
  215.     fprintf(stderr, "~VarString() a= %p, allocinc= %d\n", a, allocinc);
  216. #       endif
  217.     delete [] a;
  218.     }
  219.  
  220.     VarString& operator=(const VarString& n);
  221.     VarString& operator=(const char *);
  222.  
  223.     INLINE const char operator[](const int i) const;
  224.     INLINE char& operator[](const int i);
  225.  
  226.     operator const char *() const{ return a; }
  227.  
  228.     int length(void) const{ return len; }
  229.  
  230.     void add(char);
  231.     void add(const char *);
  232.     void add(int, const char *);
  233.     void remove(int, int= 1);
  234.  
  235.     void erase(void){ len= 0; }
  236. };
  237.  
  238. class PerlStringList;
  239. //
  240. // Implements the perl specific string functionality 
  241. //
  242. class PerlString
  243. {
  244. private:
  245.     VarString pstr;  // variable length string mechanism
  246.     
  247. public:
  248.     class substring;
  249.     
  250.     PerlString():pstr(){}
  251.     PerlString(const PerlString& n) : pstr(n.pstr){}     
  252.     PerlString(const char *s) : pstr(s){}
  253.     PerlString(const char c) : pstr(c){}
  254.     PerlString(const substring& sb) : pstr(sb.pt, sb.len){}
  255.     
  256.     PerlString& operator=(const char *s){pstr= s; return *this;}        
  257.     PerlString& operator=(const PerlString& n); 
  258.     PerlString& operator=(const substring& sb);
  259.  
  260.     operator const char*() const{return pstr;}
  261.     const char operator[](int n) const{ return pstr[n]; }
  262.  
  263.     int length(void) const{ return pstr.length(); }
  264.     
  265.     char chop(void);
  266.     
  267.     int index(const PerlString& s, int offset= 0);    
  268.     int rindex(const PerlString& s, int offset= -1);
  269.     substring substr(int offset, int len= -1);
  270.     substring substr(const Range& r){ return substr(r.start(), r.length());}
  271.         
  272.     int m(const char *, const char *opts=""); // the regexp match m/.../ equiv
  273.     int m(Regexp&);
  274.     int m(const char *, PerlStringList&, const char *opts="");
  275.     int m(Regexp&, PerlStringList&);
  276.    
  277.     int tr(const char *, const char *, const char *opts="");
  278.     int s(const char *, const char *, const char *opts="");
  279.  
  280.     PerlStringList split(const char *pat= "[ \t\n]+", int limit= -1);
  281.     
  282.     int operator<(const PerlString& s) const { return (strcmp(pstr, s) < 0); }
  283.     int operator>(const PerlString& s) const { return (strcmp(pstr, s) > 0); }
  284.     int operator<=(const PerlString& s) const { return (strcmp(pstr, s) <= 0); }
  285.     int operator>=(const PerlString& s) const { return (strcmp(pstr, s) >= 0); }
  286.     int operator==(const PerlString& s) const { return (strcmp(pstr, s) == 0); }
  287.     int operator!=(const PerlString& s) const { return (strcmp(pstr, s) != 0); }
  288.     PerlString operator+(const PerlString& s) const;
  289.     PerlString operator+(const char *s) const;
  290.     PerlString operator+(char c) const;
  291.     friend PerlString operator+(const char *s1, const PerlString& s2);
  292.  
  293.     PerlString& operator+=(const PerlString& s){pstr.add(s); return *this;}
  294.     PerlString& operator+=(const char *s){pstr.add(s); return *this;}
  295.     PerlString& operator+=(char c){pstr.add(c); return *this;}
  296.     friend substring;
  297.  
  298. private:
  299.     void insert(int pos, int len, const char *pt, int nlen);
  300.  
  301.     // This idea lifted from NIH class library -
  302.     // to handle substring LHS assignment
  303.     // Note if subclasses can't be used then take external and make
  304.     // the constructors private, and specify friend PerlString
  305.     class substring
  306.     {
  307.     public:
  308.         int pos, len;
  309.     PerlString& str;
  310.     char *pt;
  311.     public:
  312.         substring(PerlString& os, int p, int l) : str(os)
  313.     {
  314.         if(p > os.length()) p= os.length();
  315.         if((p+l) > os.length()) l= os.length() - p;
  316.         pos= p; len= l;
  317.         if(p == os.length()) pt= 0; // append to end of string
  318.         else pt= &os.pstr[p];
  319.     }
  320.  
  321.         void operator=(const PerlString& s)
  322.         {
  323.             if(&str == &s){ // potentially overlapping
  324.         VarString tmp(s);
  325.         str.insert(pos, len, tmp, strlen(tmp));
  326.         }else str.insert(pos, len, s, s.length());
  327.         }
  328.         
  329.         void operator=(const substring& s)
  330.         {
  331.         if(&str == &s.str){ // potentially overlapping
  332.         VarString tmp(s.pt, s.len);
  333.         str.insert(pos, len, tmp, strlen(tmp));
  334.         }else str.insert(pos, len, s.pt, s.len);
  335.         }
  336.  
  337.         void operator=(const char *s)
  338.         {
  339.             str.insert(pos, len, s, strlen(s));
  340.         }
  341.     };
  342. };
  343.  
  344. class PerlStringList: public PerlList<PerlString>
  345. {
  346. public:
  347.     PerlStringList(int sz= 6):PerlList<PerlString>(sz){}
  348.     // copy lists, need to duplicate all internal strings
  349.     PerlStringList(const PerlStringList& n);
  350.  
  351.     PerlStringList& operator=(const PerlList<PerlString>& n);
  352.  
  353.     int split(const char *str, const char *pat= "[ \t\n]+", int limit= -1);
  354.     PerlString join(const char *pat= " ");
  355.     int m(const char *rege, const char *targ, const char *opts=""); // makes list of sub exp matches
  356.     PerlStringList grep(const char *rege, const char *opts=""); // trys rege against elements in list
  357. };
  358.  
  359. // This doesn't belong in any class
  360. inline PerlStringList m(const char *pat, const char *str, const char *opts="")
  361. {
  362. PerlStringList l;
  363.     
  364.     l.m(pat, str, opts);
  365.     l.shift(); // remove the first element which would be $&
  366.     return l;
  367. }
  368.  
  369. // Streams operators
  370. template <class T>
  371. istream& operator>>(istream& ifs, PerlList<T>& arr)
  372. {
  373. T a;
  374.     // Should I reset arr first?
  375.     arr.reset(); // I think so, to be consistent
  376.     
  377.     while(ifs >> a){
  378.     arr.push(a);
  379. //    cout << "<" << a << ">" << endl;
  380.     };
  381.     return ifs;    
  382. }
  383.  
  384. template <class T>
  385. ostream& operator<<(ostream& os,  const PerlList<T>& arr)
  386. {
  387.  
  388.     for(int i=0;i<arr.count();i++){
  389. #ifdef    TEST
  390.     os << "[" << i << "]" << arr[i] << " ";
  391.     }
  392.     os << endl; 
  393. #else
  394.     os << arr[i] << endl;
  395.     }
  396. #endif
  397.     return os;   
  398. }
  399.  
  400. istream& operator>>(istream& ifs, PerlString& s);
  401. istream& operator>>(istream& ifs, PerlStringList& sl);
  402. ostream& operator<<(ostream& os,  const PerlString& arr);
  403. ostream& operator<<(ostream& os,  const PerlStringList& arr);
  404.  
  405. // Implementation of template functions for perllistbase
  406. template <class T>
  407. INLINE T& PerlListBase<T>::operator[](const int i)
  408. {
  409.     assert((i >= 0) && (first >= 0) && ((first+cnt) <= allocated));
  410.     int indx= first+i;
  411.         
  412.     if(indx >= allocated){  // need to grow it
  413.     grow((indx-allocated)+allocinc, i+1); // index as yet unused element
  414.     indx= first+i;              // first will have changed in grow()
  415.     }
  416.     assert(indx >= 0 && indx < allocated);
  417.  
  418.     if(i >= cnt) cnt= i+1;  // it grew
  419.     return a[indx];
  420. }
  421.  
  422. template <class T>
  423. INLINE const T& PerlListBase<T>::operator[](const int i) const
  424. {
  425.      assert((i >= 0) && (i < cnt));
  426.      return a[first+i];
  427. }
  428.  
  429. template <class T>
  430. PerlListBase<T>::PerlListBase(const PerlListBase<T>& n)
  431. {
  432.     allocated= n.allocated;
  433.     allocinc= n.allocinc;
  434.     cnt= n.cnt;
  435.     first= n.first;
  436.     a= new T[allocated];
  437.     for(int i=0;i<cnt;i++) a[first+i]= n.a[first+i];
  438. #ifdef    DEBUG
  439.     fprintf(stderr, "PerlListBase(PerlListBase&) a= %p, source= %p\n", a, n.a);
  440. #endif
  441.  
  442. }
  443.  
  444. template <class T>
  445. PerlListBase<T>& PerlListBase<T>::operator=(const PerlListBase<T>& n){
  446. //  cout << "PerlListBase<T>::operator=()" << endl;
  447.     if(this == &n) return *this;
  448. #ifdef    DEBUG
  449.     fprintf(stderr, "~operator=(PerlListBase&) a= %p\n", a);
  450. #endif
  451.     delete [] a; // get rid of old one
  452.     allocated= n.allocated;
  453.     allocinc= n.allocinc;
  454.     cnt= n.cnt;
  455.     first= n.first;
  456.     a= new T[allocated];
  457.     for(int i=0;i<cnt;i++) a[first+i]= n.a[first+i];
  458. #ifdef    DEBUG
  459.     fprintf(stderr, "operator=(PerlListBase&) a= %p, source= %p\n", a, n.a);
  460. #endif
  461.     return *this;
  462. }
  463.  
  464. template <class T>
  465. void PerlListBase<T>::grow(int amnt, int newcnt){
  466.     if(amnt <= 0) amnt= allocinc; // default value
  467.     if(newcnt < 0) newcnt= cnt;   // default
  468.     allocated += amnt;
  469.     T *tmp= new T[allocated];
  470.     int newfirst= (allocated>>1) - (newcnt>>1);
  471.     for(int i=0;i<cnt;i++) tmp[newfirst+i]= a[first+i];
  472. #ifdef    DEBUG
  473.     fprintf(stderr, "PerlListBase::grow() a= %p, old= %p, allocinc= %d\n", tmp, a, allocinc);
  474.     fprintf(stderr, "~PerlListBase::grow() a= %p\n", a);
  475. #endif
  476.     delete [] a;
  477.     a= tmp;
  478.     first= newfirst;
  479. }
  480.  
  481. template <class T>
  482. void PerlListBase<T>::add(const T& n){
  483.     if(cnt+first >= allocated) grow();
  484.     a[first+cnt]= n;
  485.     cnt++;
  486. }
  487.  
  488. template <class T>
  489. void PerlListBase<T>::add(const int ip, const T& n){
  490.     assert(ip >= 0);
  491.     if(first == 0 || (first+cnt) >= allocated) grow();
  492.     assert((first > 0) && ((first+cnt) < allocated));
  493.     if(ip == 0){ // just stick it on the bottom
  494.         first--;
  495.         a[first]= n;
  496.     }else{
  497.         for(int i=cnt;i>ip;i--) // shuffle up
  498.         a[first+i]= a[(first+i)-1];
  499.         a[first+ip]= n;
  500.     }
  501.     cnt++;
  502. }
  503.  
  504. template <class T>
  505. void PerlListBase<T>::compact(const int n){ // shuffle down starting at n
  506. int i;
  507.     assert((n >= 0) && (n < cnt));
  508.     if(n == 0) first++;
  509.     else for(i=n;i<cnt-1;i++){
  510.         a[first+i]= a[(first+i)+1];
  511.     }
  512.     cnt--;
  513. }
  514.  
  515.  
  516. // implementation of template functions for perllist
  517.  
  518. template <class T>
  519. void PerlList<T>::push(const PerlList<T>& l)
  520. {
  521.     for(int i=0;i<l.count();i++)
  522.     add(l[i]);
  523. }
  524.  
  525. template <class T>
  526. int PerlList<T>::unshift(const PerlList<T>& l)
  527. {
  528.     for(int i=l.count()-1;i>=0;i--)
  529.     unshift(l[i]);
  530.     return count();
  531. }
  532.  
  533. template <class T>
  534. PerlList<T> PerlList<T>::reverse(void)
  535. {
  536.     PerlList<T> tmp;
  537.     for(int i=count()-1;i>=0;i--)
  538.     tmp.add((*this)[i]);
  539.     
  540.     return tmp;    
  541. }
  542.  
  543. template <class T>
  544. PerlList<T> PerlList<T>::sort(void)
  545. {
  546. PerlList<T> tmp(*this);
  547. int n= tmp.scalar();
  548.  
  549.     for(int i=0;i<n-1;i++)
  550.     for(int j=n-1;i<j;j--)
  551.         if(tmp[j] < tmp[j-1]){
  552.         T temp = tmp[j];
  553.         tmp[j] = tmp[j-1];
  554.         tmp[j-1]= temp;
  555.         }
  556.     
  557.     return tmp;    
  558. }
  559.  
  560. template <class T>
  561. PerlList<T> PerlList<T>::splice(int offset, int len, const PerlList<T>& l)
  562. {
  563. PerlList<T> r= splice(offset, len);
  564.  
  565.     if(offset > count()) offset= count();
  566.     for(int i=0;i<l.count();i++){
  567.     add(offset+i, l[i]);    // insert into list
  568.     }
  569.     return r;
  570. }
  571.  
  572. template <class T>
  573. PerlList<T>  PerlList<T>::splice(int offset, int len)
  574. {
  575. PerlList<T> r;
  576.  
  577.     if(offset >= count()) return r;
  578.     for(int i=offset;i<offset+len;i++){
  579.         r.add((*this)[i]);
  580.     }
  581.  
  582.     for(i=offset;i<offset+len;i++)
  583.     compact(offset);
  584.     return r;
  585. }
  586.  
  587. template <class T>
  588. PerlList<T>  PerlList<T>::splice(int offset)
  589. {
  590. PerlList<T> r;
  591.  
  592.     if(offset >= count()) return r;
  593.     for(int i=offset;i<count();i++){
  594.     r.add((*this)[i]);
  595.     }
  596.  
  597.     int n= count(); // count() will change so remember what it is
  598.     for(i=offset;i<n;i++)
  599.     compact(offset);
  600.     return r;
  601. }
  602.  
  603. // VarString Implementation
  604. INLINE VarString::VarString(int n)
  605. {
  606.     a= new char[n];
  607.     *a= '\0';
  608.     len= 0;
  609.     allocated= n;
  610.     allocinc= n;
  611. #   ifdef    DEBUG
  612.     fprintf(stderr, "VarString(int %d) a= %p\n", allocinc, a);
  613. #   endif
  614. }
  615.  
  616. INLINE VarString::VarString(const char* s)
  617. {
  618.     int n= strlen(s) + 1;
  619.     a= new char[n];
  620.     strcpy(a, s);
  621.     len= n-1;
  622.     allocated= n;
  623.     allocinc= ALLOCINC;
  624. #   ifdef    DEBUG
  625.     fprintf(stderr, "VarString(const char *(%d)) a= %p\n", allocinc, a);
  626. #   endif
  627. }
  628.  
  629. INLINE VarString::VarString(const char* s, int n)
  630. {
  631.     a= new char[n+1];
  632.     if(n) strncpy(a, s, n);
  633.     a[n]= '\0';
  634.     len= n;
  635.     allocated= n+1;
  636.     allocinc= ALLOCINC;
  637. #   ifdef    DEBUG
  638.     fprintf(stderr, "VarString(const char *, int(%d)) a= %p\n", allocinc, a);
  639. #   endif
  640. }
  641.  
  642. INLINE VarString::VarString(char c)
  643. {
  644.     int n= 2;
  645.     a= new char[n];
  646.     a[0]= c; a[1]= '\0';
  647.     len= 1;
  648.     allocated= n;
  649.     allocinc= ALLOCINC;
  650. #   ifdef    DEBUG
  651.     fprintf(stderr, "VarString(char (%d)) a= %p\n", allocinc, a);
  652. #   endif
  653. }
  654.  
  655.  
  656. INLINE ostream& operator<<(ostream& os,  const VarString& arr)
  657. {
  658. #ifdef TEST
  659.     os << "(" << arr.length() << ")" << (const char *)arr;
  660. #else
  661.     os << (const char *)arr;
  662. #endif
  663.     
  664.     return os;    
  665. }
  666.  
  667. INLINE const char VarString::operator[](const int i) const
  668. {
  669.      assert((i >= 0) && (i < len) && (a[len] == '\0'));
  670.      return a[i];
  671. }
  672.  
  673. INLINE char& VarString::operator[](const int i)
  674. {
  675.      assert((i >= 0) && (i < len) && (a[len] == '\0'));
  676.      return a[i];
  677. }
  678.  
  679. INLINE VarString::VarString(const VarString& n)
  680. {
  681.     allocated= n.allocated;
  682.     allocinc= n.allocinc;
  683.     len= n.len;
  684.     a= new char[allocated];
  685.     strcpy(a, n.a);
  686. #ifdef    DEBUG
  687.     fprintf(stderr, "VarString(VarString&) a= %p, source= %p\n", a, n.a);
  688. #endif
  689.  
  690. }
  691. #endif
  692.  
  693.